package org.lex.game.sudoku.util;

public class Formatter {
	public static enum DurationFormat {
		/**
		 * hh:mm:ss.S
		 */
		FULL() {
			@Override
			public String format(long durationMs) {
				int hours = 0;
				int minutes = 0;
				int seconds = 0;
				int ms = 0;
				if (durationMs >= 1000) {
					ms = (int) durationMs % 1000;
					seconds = (int) durationMs / 1000;
				}
				if (seconds >= 60) {
					minutes = seconds / 60;
					seconds = seconds - minutes * 60;
				}
				if (minutes >= 60) {
					hours = minutes / 60;
					minutes = minutes - hours * 60;
				}

				StringBuilder buf = new StringBuilder();
				appendDigit(buf, hours).append(':');
				appendDigit(buf, minutes).append(':');
				appendDigit(buf, seconds);
				if (ms > 0) {
					buf.append('.');
					buf.append(ms / 100);
				}
				return buf.toString();
			}
		},
		/**
		 * mm:ss
		 */
		SHORT() {
			@Override
			public String format(long durationMs) {
				int minutes = 0;
				int seconds = 0;
				if (durationMs >= 1000) {
					seconds = (int) durationMs / 1000;
				}
				if (seconds >= 60) {
					minutes = seconds / 60;
					seconds = seconds - minutes * 60;
				}

				StringBuilder buf = new StringBuilder();
				appendDigit(buf, minutes).append(':');
				appendDigit(buf, seconds);
				return buf.toString();
			}
		};

		public abstract String format(long durationMs);

		private static StringBuilder appendDigit(StringBuilder buf, int val) {
			if (val < 10) {
				buf.append('0');
			}
			buf.append(val);
			return buf;
		}
	}

	public static final class SizeFormat {
		private static final String[] UNIT_NAMES = { "", "K", "M", "G", "T", "P" };
		private static final int[] UNIT_STEPS = { 1024, 1024, 1024, 1024, 1024, 1024 };

		public static StringBuilder format(long size, StringBuilder buf) {
			int unitIndex = 0;
			double finalSize = (double) size;
			while (true) {
				int step = UNIT_STEPS[unitIndex];
				if (finalSize >= step) {
					finalSize /= step;
					unitIndex++;
				} else {
					break;
				}
			}
			finalSize = Math.round(finalSize * 10) / 10;
			buf.append(finalSize).append(UNIT_NAMES[unitIndex]);
			return buf;
		}
	}

	public static void main(String[] args) {
		long[] sizes = { 123, 12300, 1230000, 123000000, 12300000000L };
		StringBuilder buf = new StringBuilder();
		for (long s : sizes) {
			buf.setLength(0);
			System.out.println(s + " :" + SizeFormat.format(s, buf));
		}
	}
}
